package bma.common.langutil.ai.stack;

import bma.common.langutil.core.Function;

/**
 * 
 * @author guanzhong
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 * @param <F_TYPE>
 * @param <T_TYPE>
 */
public abstract class AIStackConvert<F_TYPE, T_TYPE> extends
		AIStackAbstract<F_TYPE> {

	private AIStack<T_TYPE> delegate;

	public AIStackConvert(AIStack<T_TYPE> delegate) {
		super();
		this.delegate = delegate;
	}

	public AIStack<T_TYPE> delegate() {
		return delegate;
	}

	@Override
	public AIStack<?> getParent() {
		return delegate;
	}

	@Override
	public boolean success(F_TYPE result) {
		try {
			return convert(result);
		} catch (Exception e) {
			return this.delegate.failure(e);
		}
	}

	@Override
	public boolean failure(Throwable t) {
		return this.delegate.failure(t);
	}

	public boolean successConvert(T_TYPE v) {
		return this.delegate.success(v);
	}

	protected abstract boolean convert(F_TYPE result);

	public static <FT, TT> AIStackConvert<FT, TT> apply(AIStack<TT> stack,
			final Function<FT, TT> transform) {
		return new AIStackConvert<FT, TT>(stack) {
			@Override
			protected boolean convert(FT result) {
				TT v = transform.apply(result);
				successConvert(v);
				return true;
			};
		};
	}
}
